package cloud.xiangyixiang.www.spring.boot.java.basics.utils;

import cloud.xiangyixiang.www.spring.boot.java.basics.pojo.bo.UserBo;

import java.util.Arrays;

/**
 * <p>
 * 数组Copy工具类
 * </p>
 *
 * @author weixin
 * @date 2023/8/31 20:26
 */
public class ArrayCopyUtil {

    /**
     * 浅拷贝
     * @param original {@link byte[]}
     * @param from {@link int}
     * @param to {@link int}
     */
    public static void copyOfRange(byte[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0){
            throw new IllegalArgumentException(from + " > " + to);
        }

        byte[] copy = new byte[newLength];
        System.arraycopy(original, from, copy, 0,
                Math.min(original.length - from, newLength));
        System.out.println(copy);
        System.out.println();
    }

    /**
     * 基本类型数组复制-整型数组
     *
     *  把从索引0开始的2个数字复制到索引为3的位置上
     */
    public static void copySelf() {
        int[] ids = { 1, 2, 3, 4, 5 };
        System.out.println(Arrays.toString(ids));
        // 把从索引0开始的2个数字复制到索引为3的位置上
        System.arraycopy(ids, 0, ids, 3, 2);
        System.out.println(Arrays.toString(ids));
        System.out.println();
    }

    /**
     * 基本类型数组复制-整型数组
     *
     *  将数据的索引1开始的3个数据复制到目标的索引为0的位置上
     */
    public static void copyToOther() {
        int[] ids = { 1, 2, 3, 4, 5 };
        // 将数据的索引1开始的3个数据复制到目标的索引为0的位置上
        int[] other = new int[5];
        System.arraycopy(ids, 1, other, 0, 3);
        //[1, 2, 3, 4, 5]深复制
        System.out.println(Arrays.toString(ids));
        //[2, 3, 4, 0, 0]
        System.out.println(Arrays.toString(other));
        System.out.println();
    }


    /**
     * Object数组复制-对象数组复制为整型数组
     *
     *  如果是类型转换问题，只获取整形
     */
    public static void getIntegerArrayFromObjectArray() {
        Object[] obj1 = { 1, 2, 3, "4", "5" };
        Integer[] obj2 = new Integer[5];

        try {
            System.arraycopy(obj1, 0, obj2, 0, obj1.length);
        } catch (Exception e) {
            System.out.println("transfer exception:"+e);
        }
        System.out.println(Arrays.toString(obj1));
        System.out.println(Arrays.toString(obj2));
        System.out.println();
    }


    /**
     * Object数组复制-对象数组复制为字符串数组
     *
     * 获取Object数组中的字符串类型数据
     */
    public static void getStringArrayFromObjectArray1() {
        Object[] obj3 = { 1, 2, 3, "4", "5" };
        String[] obj4 = new String[5];
        try {
            System.arraycopy(obj3, 2, obj4, 2, 3);
        } catch (Exception e) {
            //transfer exception:java.lang.ArrayStoreException
            System.out.println("transfer exception:"+e);
        }
        System.out.println(Arrays.toString(obj3));
        //[null, null, null, null, null]
        System.out.println(Arrays.toString(obj4));
        System.out.println();
    }

    /**
     * Object数组复制-对象数组复制为字符串数组
     *
     * 获取Object数组中的字符串类型数据
     */
    public static void getStringArrayFromObjectArray2() {
        Object[] obj3 = { 1, 2, 3, "4", "5" };
        String[] obj4 = new String[5];
        try {
            System.arraycopy(obj3, 3, obj4, 3, 2);
        } catch (Exception e) {
            System.out.println("transfer exception:"+e);
        }
        System.out.println(Arrays.toString(obj3));
        //[null, null, null, 4, 5]
        System.out.println(Arrays.toString(obj4));
        obj3[3] = "ZhangSan";
        System.out.println("查看是浅复制还是深复制~~~~~");
        System.out.println(Arrays.toString(obj3));
        System.out.println(Arrays.toString(obj4));
        System.out.println();
    }

    /**
     * 数组复制-多维数组
     */
    public static void multidimensionalArrays() {
        int[] arr1 = {1, 2};
        int[] arr2 = {3, 4};
        int[] arr3 = {5, 6};

        int[][] src = new int[][]{arr1, arr2, arr3};

        System.out.println("原始模样：" + src);
        System.out.println("原始模样 toString: " + Arrays.toString(src));
        int[][] dest = new int[3][];
        System.arraycopy(src, 0, dest, 0, 3);

        System.out.println("改变前:: ");
        print("src: ", src);
        print("dest: ", dest);

        //原数组改变后观察新数组是否改变，改变->浅复制，不改变->深复制
        src[0][0] = -1;

        System.out.println("改变后:: ");
        print("src: ", src);
        print("dest: ", dest);

        System.out.println();
    }

    /**
     * 对象数组复制-单个对象
     */
    public static void arrayBeanCopy() {
        UserBo user1 = new UserBo("zs",18);
        UserBo user2 = new UserBo("ls",18);
        UserBo user3 = new UserBo("ww",18);

        UserBo[] userArraySrc = {user1, user2, user3};

        UserBo[] userArrayDest = new UserBo[3];

        System.out.println("------------未改变原对象------------------");
        System.out.println("对象复制，原始模样：" + Arrays.toString(userArraySrc));

        // 对象复制
        System.arraycopy(userArraySrc, 0, userArrayDest, 0, userArraySrc.length);

        System.out.println("userArrayDest," + Arrays.toString(userArrayDest));

        System.out.println("------------改变原对象------------------");
        userArraySrc[0] = new UserBo("su",20);

        System.out.println("***" + Arrays.toString(userArraySrc));
        System.out.println("***" + Arrays.toString(userArrayDest));


        System.out.println();
    }


    /**
     * 二维数组toString()
     * @param string {@link String}
     * @param arr {@link int[][]}
     */
    private static void print(String string, int[][] arr) {
        System.out.print(string);
        for (int[] a : arr) {
            for (int i : a) {
                System.out.print(i + " ");
            }
            System.out.print(",");
        }
        System.out.println();
    }

}
